package cn.leftsite.juc.tools;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁示例
 *
 * @author wangjinqiang
 * @date 2019-06-04
 */
public class ReadWriteLockDemo {
    private static final Lock lock = new ReentrantLock();

    private static final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    public static final Lock rLock = readWriteLock.readLock();
    public static final Lock wLock = readWriteLock.writeLock();

    private int value;

    public Object handleRead(Lock lock) throws InterruptedException {
        lock.lock();
        try {
            // 模拟读取操作,读操作耗时越多，读写锁的操作越明显
            Thread.sleep(1000);
            return value;
        } finally {
            lock.unlock();
        }
    }

    public void handleWrite(Lock lock, int index) throws InterruptedException {

        lock.lock();
        try {
            Thread.sleep(1000);
            value = index;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockDemo readWriteLockDemo = new ReadWriteLockDemo();
        Runnable readRunnable = ()->{
            try {
                readWriteLockDemo.handleRead(rLock);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Runnable writeRunnable = ()->{
            try {
                readWriteLockDemo.handleWrite(wLock,new Random().nextInt());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        for (int i = 0; i < 18; i++) {
            new Thread(readRunnable).start();
        }

        for (int i = 18; i < 20; i++) {
            new Thread(writeRunnable).start();
        }
    }

}
